package cn.turboinfo.fuyang.api.scheduler.listener.product

import cn.turboinfo.fuyang.api.domain.common.service.product.ProductService
import cn.turboinfo.fuyang.api.domain.common.service.shop.HousekeepingShopService
import cn.turboinfo.fuyang.api.entity.common.constant.EventConstants
import cn.turboinfo.fuyang.api.entity.common.event.shop.ShopGeoChangedEvent
import cn.turboinfo.fuyang.api.provider.common.constant.GeoConstants
import cn.turboinfo.fuyang.api.provider.common.service.geo.GeoService
import cn.turboinfo.fuyang.api.provider.rabbit.constant.RabbitConstants
import mu.KotlinLogging
import org.springframework.amqp.core.Binding
import org.springframework.amqp.core.BindingBuilder
import org.springframework.amqp.core.Queue
import org.springframework.amqp.core.TopicExchange
import org.springframework.amqp.rabbit.annotation.RabbitHandler
import org.springframework.amqp.rabbit.annotation.RabbitListener
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component
import java.math.BigDecimal

/**
 * 由于门店位置变更维护服务产品的位置
 */
@Configuration
class ProductGeoChangedByShopListenerConfig {

    companion object {
        private const val Name = "ProductGeoChangedByShop"

        private const val Topic = EventConstants.TopicShopGeoChangedEvent

        const val QueueName =
            "${RabbitConstants.QueueEventPrefix}${Topic}.${Name}"

        const val RoutingKey = "${RabbitConstants.RoutingKeyEventPrefix}${Topic}"
    }


    @Bean
    fun productGeoChangedByShopQueue(): Queue {
        return Queue(QueueName)
    }

    @Bean
    protected fun productGeoChangedByShopBinding(
        productGeoChangedByShopQueue: Queue,
        eventExchange: TopicExchange
    ): Binding {
        return BindingBuilder.bind(productGeoChangedByShopQueue)
            .to(eventExchange)
            .with(RoutingKey)
    }

    @Component
    @RabbitListener(queues = [QueueName])
    class ProductGeoChangedByShopListener(
        private val productService: ProductService,
        private val housekeepingShopService: HousekeepingShopService,
        private val geoService: GeoService,
    ) {

        private val logger = KotlinLogging.logger {}

        @RabbitHandler
        fun process(event: ShopGeoChangedEvent) {
            runCatching {
                event
                    .let {
                        housekeepingShopService.getByIdEnsure(it.shopId)
                    }
                    ?.apply {
                        if (longitude > BigDecimal.ZERO && latitude > BigDecimal.ZERO) {
                            productService.findByShopIdCollection(listOf(id))
                                .onEach {
                                    geoService.add(
                                        GeoConstants.STORE_PRODUCT,
                                        it.id.toString(),
                                        longitude.toDouble(),
                                        latitude.toDouble()
                                    )
                                    logger.error {
                                        "门店位置变更, 维护门店产品位置信息为门店位置, productId=$id"
                                    }
                                }
                        }
                    }
            }
                .onFailure {
                    logger.error(it) { "处理门店位置变更时维护产品位置信息出错" }
                }
        }

    }
}